import storage from "store";
import { serialize } from "/@/util/util";
import axios from "axios";
import qs from "qs";
import NProgress from "nprogress"; // progress bar
import { getErrorCode, ErrorCodeKey } from "/@/const/errorCode";
import { notification } from "ant-design-vue";
import "nprogress/nprogress.css";
import store from "/@/store"; // progress bar style
import router from "/@/router";
import { MutationTypes as UserMutationTypes } from "../store/user/mutation-types";
import { requestTimeout, requestBaseURL } from "../router/config";
import { UserActionTypes } from "../store/user/action-types";

const openErrorMessage = (msg: string) => {
  let description = "";
  if (msg === undefined) {
    description = "服务器出了点小差";
    console.error("发生空指针");
  } else if (msg.includes("###")) {
    console.error(msg);
    description = "数据库查询发生错误, 请查看控制台";
  } else {
    console.warn(msg);
    description = msg;
  }
  // 判断测试站直接报错但正式站不提示弹框错误
  notification.open({ message: "提示", description });
};

axios.defaults.timeout = requestTimeout;
axios.defaults.baseURL = requestBaseURL;

// const source = axios.CancelToken.source();
// 返回其他状态吗
axios.defaults.validateStatus = (status) => status >= 200 && status <= 500; // 默认的

// 跨域请求，允许保存cookie
axios.defaults.withCredentials = true;
// NProgress Configuration
NProgress.configure({
  showSpinner: false,
});

// HTTPrequest拦截
axios.interceptors.request.use(
  (config) => {
    NProgress.start(); // start progress bar
    const isToken = (config.headers || {}).isToken === false;
    const accessToken = storage.get(UserMutationTypes.SET_ACCESS_TOKEN);
    if (accessToken && !isToken) {
      config.headers.Authorization = `Bearer ${accessToken}`; // token
    }
    // config.cancelToken = source.token;
    // headers中配置serialize为true开启序列化
    if (config.method === "post" && config.headers.serialize) {
      config.data = serialize(config.data);
      delete config.data.serialize;
    }
    if (config.method === "get") {
      config.paramsSerializer = (params) => qs.stringify(params, { arrayFormat: "brackets" });
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// eslint-disable-next-line consistent-return
axios.interceptors.response.use(
  (res: any) => {
    NProgress.done();
    const status = (res.status || 200) as ErrorCodeKey;
    const message = getErrorCode(status, res.data.message);
    if (status === 401) {
      openErrorMessage(message);
      store.dispatch(UserActionTypes.User_Clear_Info).then(() => {
        router.push({ path: "/login" });
      });
    } else if (/4\d\d/.test(`${status}`)) {
      openErrorMessage(message);
      return res.data;
    } else {
      if (res.data.code === 1) {
        openErrorMessage(message);
      }
      return res.data;
    }
  },
  (error) => {
    // 处理其他异常
    NProgress.done();
    return Promise.reject(new Error(error));
  }
);

export default axios;
